home *** CD-ROM | disk | FTP | other *** search
- /* launch.c */
-
- /* Copyright © 1989 by Donald T. Meyer, Stormgate Software
- * All Rights Reserved
- */
-
-
-
- #include "rxil.h"
-
- #include <string.h>
-
-
-
- /* NAME
- * RxilLaunch
- *
- * SYNOPSIS
- * result = RxilLaunch( rxi )
- *
- * LONG result;
- *
- * struct RxilInvocation *rxi;
- *
- * FUNCTION
- * Launch an ARexx program by sending an invocation message
- * to the RexxMaster process. The RxilInvocation structure
- * which is allocated prior to this call via RxilCreateRxi()
- * contains the information neccessary to launch the program.
- *
- * INPUTS
- * rxi A pointer to an initialized RxilInvocation structure.
- *
- * RESULT
- * Zero if the launch was successful, non-zero otherwise.
- *
- * SIDES
- *
- * HISTORY
- * 01-Aug-89 Creation.
- *
- * BUGS
- *
- * SEE ALSO
- * RxilCreateRxi(), RxilDeleteRxi()
- */
-
- LONG RxilLaunch( struct RxilInvocation *rxi )
- {
- struct RexxArg *arg;
- struct MsgPort *rmast, *replyport;
- struct RexxMsg *rexxmsg;
- int i;
- int ac=0;
- UWORD len;
-
-
- /* Make call "safe" even if RxilInit() failed */
- if( global_rdef == NULL )
- {
- return( -1 );
- }
-
-
- /* Replys can come in at either port. */
- replyport = global_rdef->SecretPort ?
- global_rdef->SecretPort : global_rdef->PublicPort;
-
-
- if( rxi->State != RXIL_STATE_AVAILABLE )
- {
- /* A command is already launched, (using this structure),
- * or the reply has not yet been dealt with.
- */
- return( -1 );
- }
-
-
- /* Allocate a packet to send to rexxmaster */
- rexxmsg = CreateRexxMsg( replyport, rxi->FileExt, rxi->CommAddr );
- if( rexxmsg == NULL )
- {
- return( -1 );
- }
-
- /* Allocate an argument string for the command name and args */
- arg = CreateArgstring( rxi->Name, strlen( rxi->Name ) );
- if( arg == NULL )
- {
- DeleteRexxMsg( rexxmsg );
- return( -1 );
- }
-
- ARG0(rexxmsg) = (STRPTR)arg;
-
-
- if( rxi->Type == RXFUNC )
- {
- /* This is a Function invocation. */
-
- /* Turn the arguments into Rexx Argstrings and place in the
- * RexxMsg packet.
- */
- for( i=1; i<=MAXRMARG; i++ )
- {
- if( rxi->FuncArg[i] == NULL )
- {
- /* Empty argument slot, consider it the last */
- break;
- }
-
- /* We can either determine the argument length, or the client
- * can pre-set a count.
- */
- len = rxi->CountArgs ?
- rxi->ArgLen[i] : strlen(rxi->FuncArg[i]);
-
- rexxmsg->rm_Args[i] =
- (STRPTR)CreateArgstring( rxi->FuncArg[i], len );
-
- ac++;
-
- if( rexxmsg->rm_Args[i] == NULL )
- {
- /* Unable to create this argstring. Cleanup and return
- * a failure code.
- */
- for( i=0; i<=MAXRMARG; i++ )
- {
- if( rexxmsg->rm_Args[i] != NULL )
- {
- DeleteArgstring( (struct RexxArg *)
- (rexxmsg->rm_Args[i]) );
- }
- }
-
- DeleteRexxMsg( rexxmsg );
- return( -1 );
- }
- }
-
- rexxmsg->rm_Action = RXFUNC | rxi->ActionFlags | ac;
- }
- else
- {
- /* This is a Command invocation */
- rexxmsg->rm_Action = RXCOMM | rxi->ActionFlags;
- }
-
-
- /* Set up the I/O streams for the macro */
-
- if( rxi->Parent == NULL )
- {
- /* This is an original launch from the application */
- if( rxi->Console )
- {
- /* And there is a console spec. Use it. */
- RxilOpenConsole( rxi->Console, rexxmsg );
- }
- }
- else
- {
- /* This is a loopback child of a macro. Use the I/O fields
- * from the parent message.
- */
- rexxmsg->rm_Stdin = rxi->Parent->rm_Stdin;
- rexxmsg->rm_Stdout = rxi->Parent->rm_Stdout;
- }
-
-
- Forbid();
- if( ( rmast = FindPort( rxi->IHostPort ) ) != NULL )
- {
- PutMsg( rmast, (struct message *)rexxmsg );
- }
- Permit();
-
- if( rmast == NULL )
- {
- /* we could not find the REXX port, this failed!
- * Cleanup and return a failure code.
- */
- for( i=0; i<=MAXRMARG; i++ )
- {
- if( rexxmsg->rm_Args[i] != NULL )
- {
- DeleteArgstring( (struct RexxArg *)
- (rexxmsg->rm_Args[i]) );
- }
- }
-
- if( rxi->Console )
- {
- RxilCloseConsole( rexxmsg );
- }
-
- DeleteRexxMsg( rexxmsg );
- return( -1 );
- }
-
-
- /* If we make it here, we have hopefully launched. */
-
- /* Set this so we can recognize the reply, and to let us know that
- * we have a command pending.
- */
- rxi->RexxMsg = rexxmsg;
- rxi->State = RXIL_STATE_PENDING;
-
-
- if( rxi->CommAddr == global_rdef->SecretPortName )
- {
- #if 0
- if( global_rdef->Locked )
- {
- /* Since we are locked, we should not be launching any macros
- * which have the secret port as their initial host address.
- */
- return( -1 );
- }
- #endif
-
- /* Increment the locked count.
- */
- global_rdef->LockCount++;
- }
-
-
- if( rxi->Parent == NULL )
- {
- /* This is a launch originated within the application. */
- if( FlagIsClear( global_rdef->Flags, RXIL_NO_ABORT ) )
- {
- /* Post the macro cancel requester */
- RxilPostCancel();
- }
- }
-
-
- return( 0 );
- }
-
-